<template>
  <div class="app-container home">
     <el-card class="box-card"   shadow="never">
    <el-row>
      <el-col :span="8">

          <!-- 显示在线列表数-->
          <el-row>
           <el-col :span="16">
             <div class="number">在线设备数量：<span>{{deviceNum}}</span></div>
           </el-col>
           <el-col :span="8" style="text-align: center;">
             <el-button type="primary" icon="el-icon-refresh" @click="refreshDevice()"  size="mini"></el-button>
           </el-col>
          </el-row>

          <!--设备列表 -->
          <el-table ref="singleTable" :data="tableData"  style="width: 100%;margin-top: 15px;"  highlight-current-row   @current-change="handleCurrentChange" :row-class-name="tableRowClassName">>
              <el-table-column  prop="deviceCode" label="设备编号" > </el-table-column>
              <el-table-column  prop="realTimeState" label="状态" > </el-table-column>
              <el-table-column  label="绑定电子围栏" >
                <template #default="scope">
                   <el-tag v-if="scope.row.allow">绑定</el-tag>
                  <el-tag  type="danger" v-else>未绑</el-tag>
                </template>
              </el-table-column>
              <el-table-column  prop="deviceName" label="操作" >
                <template #default="scope">
                  <el-button type="danger" size="mini" v-if="scope.row.allow" @click="directives(scope.row)">发送指令</el-button>
                </template>
              </el-table-column>
           </el-table>

      </el-col>

      <el-col :span="16">
           <baidu-map class="bm-view" ak="3LgMlTyAIzk2ok2Sn5ZY6NPPmVQjMFch" center="重庆" :zoom="zoom" @ready="handler">
              <bm-navigation anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-navigation>
              <bm-map-type :map-types="['BMAP_NORMAL_MAP', 'BMAP_HYBRID_MAP']" anchor="BMAP_ANCHOR_TOP_LEFT"></bm-map-type>
              <!-- 绘制电子围栏区域 -->
              <template v-for="(item,index) in tableData">
                 <bm-circle v-if="item.allow"  :center="calcPoint(item.electricFenceResp)"  :radius="item.electricFenceResp.radius" stroke-color="blue" :stroke-opacity="0.5" :stroke-weight="2"   :editing="false">
                 </bm-circle>
                 <bm-label v-if="item.allow" class="my-maptip" :content="showInfo(item.electricFenceResp)" :offset="{width: -55, height: -50}" :position="calcPoint(item.electricFenceResp)" :labelStyle="{color: 'red', fontSize : '10px'}" />

                 <bm-marker :position="calcMarkerPoint(item)" @click="infoWindowOpen(item)" >
                   <bm-info-window :position="calcMarkerPoint(item)"   :show="item.showFlag" @close="infoWindowClose(item)" >
                      <p v-text="'编号：'+item.deviceCode"></p>
                      <p v-text="'位置:'+item.lon+',' +item.lat" ></p>
                      <p v-if="item.status==='1'"   >设备状态:正常</p>
                      <p v-else-if="item.status==='2'" >设备状态:维修中</p>
                      <p v-else>设备状态:报废</p>
                      <p v-text="'实时状态'+item.realTimeState"></p>
                    </bm-info-window>
                  </bm-marker>

              </template>
           </baidu-map>
      </el-col>
      <!-- <el-col :span="4">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span>卡片名称</span>
            <el-button style="float: right; padding: 3px 0" type="text">操作按钮</el-button>
          </div>
          <div v-for="o in 4" :key="o" class="text item">
            {{'列表内容 ' + o }}
          </div>
        </el-card>
      </el-col> -->
    </el-row>

     </el-card>

    <el-dialog title="发送指令" :visible.sync="centerDialogVisible" width="30%" center>
        <el-form :model="queryform" style="width: 90%;">
          <el-form-item label="发送指令">
            <el-select v-model="queryform.controlId" clearable placeholder="请选择需要发送的指令">
              <el-option v-for="(item, index) in dict.type.instruction_type" :key="index" :label="item.label" :value="item.value"></el-option>
            </el-select>
          </el-form-item>
          <template v-if="queryform.controlId==1">
            <el-form-item label="指令ID:">
              <!-- <el-input v-model="queryform.instructId" disabled></el-input> -->
              <label>{{ cardform.instructId }}</label>
            </el-form-item>
            <el-form-item label="设备编号:">
              <!-- <el-input v-model="queryform.deviceId" disabled></el-input> -->
              <label>{{ cardform.deviceId }}</label>
            </el-form-item>
            <el-form-item label="电子围栏名称:">
              <label>{{ queryform.name }}</label>
            </el-form-item>
            <label>预览Json格式:</label>
            <el-card class="box-card" style="margin-top: 20px">
              <json-view :data="cardform"/>
            </el-card>
          </template>
          <template v-if="queryform.controlId==2">
            <el-form-item label="指令ID:">
              <label>{{ clearform.instructId }}</label>
              <!-- <el-input v-model="clearform.instructId" disabled></el-input> -->
            </el-form-item>
            <el-form-item label="区域编码:">
              <label>{{ clearform.sysOrgCode }}</label>
              <!-- <el-input v-model="clearform.sysOrgCode" disabled></el-input> -->
            </el-form-item>
            <label>预览Json格式:</label>
            <el-card class="box-card" style="margin-top: 20px">
              <json-view :data="clearform"/>
            </el-card>
          </template>
        </el-form>
        
        <span slot="footer" class="dialog-footer">
          <el-button @click="reset()">取 消</el-button>
          <el-button type="primary" @click="senddirectives()">确 定</el-button>
        </span>
    </el-dialog>


  </div>
</template>

<script>

import {  BaiduMap, BmMarker,BmLabel,BmInfoWindow, BmNavigation,BmGeolocation,BmCityList,BmControl,BmAutoComplete,BmMapType,BmCircle} from 'vue-baidu-map'
import { listApi } from '@/api/hat/device.js'
import {sendInstructionsApi} from '@/api/hat/fence.js'
import { Loading } from 'element-ui';
import jsonView from 'vue-json-views'
// uuid引用
import { v4 as uuidv4 } from 'uuid';

  //自定义动态加载
  var downloadLoadingInstance;



export default {
  name: "Index",
  dicts: ['device_binding_status','instruction_type'],
  components: {
    BaiduMap,
    BmNavigation,
    BmGeolocation,
    BmCityList,
    BmMarker,
    BmControl,
    BmAutoComplete,
    BmMapType,
      BmCircle,
      BmLabel,
    BmInfoWindow,
    jsonView
  },
  data () {
    return {
      //表格单选状态
      currentRow: null,
      queryParams: {

      },
      cardform: {
        
      }
      ,
      tableData: [
      ],
      zoom: 14,
      BMap: undefined,
      map: undefined,
      url: "ws://127.0.0.1:8080/websocket/",
      //当前连接的socket对象
      ws: null,
      //存储marker点对象
      markerList: [],
      centerDialogVisible: false,
      queryform: {},
      clearform:{}
    };
  },
  created () {
    //获取当前用户
    const username = this.$store.getters.name
    this.url = "ws://127.0.0.1:8080/websocket/" + username
  },
  beforeDestroy () {
    console.log("beforeDestroy")
    this.closeWebSocket();
  },
  destroyed () {
    console.log("destroyed")
    this.ws.close();
    delete this.socket;
  },
  methods: {
    //重置对话框
    reset () {
      this.centerDialogVisible = false
      this.queryform = {}
      this.clearform={}
    },
    //发送指令
    directives (val) {
      // console.log(val)
      this.centerDialogVisible = true
      this.queryform = {
        name:val.electricFenceResp.name
      }
      this.cardform = {
        // instructId: val.deviceCode,
        instructId: uuidv4().substring(0, 8),
        deviceId: val.deviceId,
        centerLat: val.electricFenceResp.latitude,
        centerLon: val.electricFenceResp.longitude,
        radius: val.electricFenceResp.radius,
      },
        this.clearform = {
        instructId: uuidv4().substring(0, 8),
        sysOrgCode:val.sysOrgCode
        }
    },
    senddirectives () {
      this.$confirm('确定发送指令吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
      }).then(() => {
        if (this.queryform.controlId == 1) {
          sendInstructionsApi(this.cardform)   
          // console.log(this.cardform)
        } else {
          sendInstructionsApi(this.clearform)   
          // console.log(this.clearform)
        }
        this.$message({
          type: 'success',
          message: '发送成功!'
        })
        this.centerDialogVisible = false
        //重置表单
        this.reset()
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消'
          });          
        })
    }
    ,
    infoWindowClose (item) {
         item.showFlag=false
      },
      infoWindowOpen (item) {
        item.showFlag=true
      },
    //构造坐标，还原数据
    calcPoint(item){
      return  {
       lng: item.longitude,
       lat: item.latitude
       }
    },
    //电子设备的位置
    calcMarkerPoint(item){
      return  {
       lng: item.lon,
       lat: item.lat
       }
    },
    tableRowClassName ({ row, rowIndex }) {
      if (row.realTimeState === '离线') {
        return 'danger-row';
      } else {
        if (row.realTimeState === '正常') {
          return '';
        } else if (row.stats === '2') {
          return 'warning-row';
        } else if (row.status === '1') {
          return 'warning-row';
        }
      }
      return '';
    },
    //在百度在图上动态添加点
    createMarker () {
      //清空点
      if (!this.map) {
        return
      }
      this.map.clearOverlays();
      this.markerList = []

      console.log("清空地图，重绘点")
      // 创建点标记
      for (let item of this.tableData) {

        if (!item.realTimeState === '正常') {
          this.markerList.push(null);
          continue;
        }

        let point = new BMap.Point(item.lon, item.lat);

        //在点上面添加设备编号
        let opts = {
          position: new BMap.Point(point), // 指定文本标注所在的地理位置
          offset: new BMap.Size(-65, -35) // 设置文本偏移量
        };
        // 创建文本标注对象
        let label = new BMap.Label(item.deviceCode, opts);
        // 自定义文本标注样式
        label.setStyle({
          color: 'blue',
          borderRadius: '5px',
          borderColor: '#ccc',
          padding: '10px',
          fontSize: '14px',
          height: '30px',
          lineHeight: '20px',
          fontFamily: '微软雅黑'
        });

        let marker = new BMap.Marker(point);
        marker.setLabel(label);

        //添加到临时集合中
        this.markerList.push(marker);

        // 在地图上添加点标记
        this.map.addOverlay(marker);

        // 创建信息窗口
        var iwOpts = {
          width: 200,
          height: 100,
          title: ''
        };

        //var infoWindow = new BMap.InfoWindow('地址：北京市东城区王府井大街88号乐天银泰百货八层', iwOpts);
        const that = this;
        //自定义一个方法
        marker.clickFun = function () {
          that.map.openInfoWindow(infoWindow, point); // 开启信息窗口
        }

        let infoWindow = this.createInfoWindow(item)
        // 点标记添加点击事件
        marker.addEventListener('click', function () {
          //this.map.openInfoWindow(infoWindow, point); // 开启信息窗口
          this.clickFun();
        });
      }
    },
    //对应不同的Marker创建不同的InfoWindow
    createInfoWindow (item) {
      var sContent = `
       <div class='mark_tip_top'>
         <p>设备：${item.deviceCode}</p>
         <p>位置：<span>经度：${item.lon},纬度：${item.lat}</span></p>
        <div>`;
      var iw = new BMap.InfoWindow("", { enableMessage: false });
      iw.setTitle("");
      iw.setContent(sContent);
      return iw;
    },
    handler ({ BMap, map }) {

      this.BMap = BMap
      this.map = map
      //允许鼠标绽放地图
      this.map.enableScrollWheelZoom(true);
      this.zoom = 13
      //查询数据库的设备
      this.fetchDeviceList()
    },
    //设定选中某一行的列
    setCurrent (row) {
      this.$refs.singleTable.setCurrentRow(row);
    },
    //点击左边表格
    handleCurrentChange (val) {
      console.log(val)
      this.currentRow = val;

      val.showFlag=true
       var point = new BMap.Point(val.lng, val.lat)
      this.map.setCenter( point);

    },
    //重新加载设备列表
    refreshDevice () {
      this.setCurrent()
      this.currentRow = undefined
      this.fetchDeviceList()
    },

    fetchDeviceList () {
      downloadLoadingInstance = Loading.service({ text: "正在查询设备，请稍后", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })

      listApi().then(resp => {
        this.tableData = resp.data
        //创建地图点
        //this.createMarker()
        //关闭动画
        downloadLoadingInstance.close();

        //与后台建立长连接
        if (!this.ws) {
          this.connectionWebSocket()
        }

      }).catch(e => {
        //关闭动画
        downloadLoadingInstance.close();
      })
    },
    connectionWebSocket () {
      const wsuri = this.url;
      //创建一个webscoket对象
      if (this.ws && this.ws.connected) {
        return;
      }

      if ('WebSocket' in window) {
        this.ws = new WebSocket(wsuri)
        const self = this;
        //与后台websocket建立连接并且成功的时候回调
        this.ws.onopen = function (event) {
          self.$message('与后台websocket连接成功');
        };
        //收到后台发送过来的消息
        this.ws.onmessage = function (event) {
          const data = event.data
          const jsonData = JSON.parse(data);
          console.log(jsonData)
          //接收到的是设备传递过来的数据
          if (jsonData.type === 'device_info') {
            self.updateDeviceInfo(jsonData)
          }


        };
        //收到关闭方法
        this.ws.onclose = function (event) {
          console.log(event)
          this.ws = null;
        };

      } else {
        this.$message.error('当前浏览器不支持WebSocket');
        return
      }
    },
    closeWebSocket () {
      //手动与后台websocket关闭
      if (this.ws && this.ws.connected) {
        this.ws.disconnect();
      }
    },
    //更新设备的数据信息
    updateDeviceInfo (jsonData) {
      //循环遍历tableData的数据
      const deviceList = JSON.parse(jsonData.data);
      for (let index in this.tableData) {
        let row = this.tableData[index]
        let searchArr = deviceList.filter(p => p.deviceId === row.deviceId);

        if (searchArr.length > 0) {
          const orgData = searchArr[0];
          row.realTimeState = '正常'
          row.updateTime = orgData.createTime
          row.lon = orgData.lon
          row.lat = orgData.lat
          row.deviceName = orgData.deviceName

          //取出row的电子围栏信息 allow=true   计算距离是否超过，如果超过了，向后台发消息，写入数据库
          //this.ws.send( {type:'insert_log','rows设备离开了电子围栏'});
        } else {
          // 向后台发消息，写入数据库
            //this.ws.send( {type:'insert_log','rows离线了'});
          //不在线了
          row.realTimeState = '离线'
          row.updateTime = jsonData.timestamp
        }

      }

    },
    showInfo(item){
      return `<p>围栏名称:${item.name}</p>
      <p>负责人:${item.userName}</p>
             <p>联系电话:${item.mobile}</p>`

    },
    //构造坐标，还原数据
    calcPoint (item) {
      return {
        lng: item.longitude,
        lat: item.latitude
      }
    },
    updateCirclePath (e) {
      console.log(e)
      console.log(e.target.getCenter())
      console.log(e.target.getRadius())
      setTimeout(() => {
        this.form.radius = e.target.getRadius()
      }, 500)
    },
  },
    computed: {
      deviceNum () {
        return this.tableData.filter(p => p.realTimeState === "正常").length;
      }
    }
  };
</script>


<style>
  .el-table .warning-row {
    background: #E6A23C;
  }

  .el-table .danger-row {
    background: #F56C6C;
  }

  .el-table .success-row {
    background: #f0f9eb;
  }
</style>
<style scoped lang="scss">

  .bm-view {
    width: 100%;
    height:800px;
  }

  ul {
    padding: 0;
    margin: 0;
  }

  .number{
    font-weight: 800;
  }


</style>

